package superpay

import (
    "errors"
	"strings"
	"thirdpaysdk/core"
	"thirdpaysdk/utils/signature"
	"encoding/json"
	"thirdpaysdk/utils/mapstruct"
	//"github.com/astaxie/beego"
)

//小程序统一下单
type UnifieldReq struct {
	Service        string   `json:"service"`    //用来映射服务中方法实现          
	MchId          string   `json:"mch_id"`     //平台方商户编号      
	Charset        string   `json:"charset"`    //编码类型
	SignType       string   `json:"sign_type"`  //签名类型
	Sign           string   `json:"sign"`            //签名
	Memo           string   `json:"memo,omitempty"`  //备注
	Version        string   `json:"version"`         //版本
	CallBackUrl    string   `json:"call_back_url"`        //异步回调地址
	NotifyUrl      string   `json:"notify_url,omitempty"` //回调地址(暂未使用)
	StoreName      string   `json:"store_name"`           //店铺名称
	ReceviceId     string   `json:"recevice_id"`          //收款方唯一标识(接入平台商户编号)
	MchOrderNo     string   `json:"mch_order_no"`         //业务号/商户订单号
	PayWay         string   `json:"pay_way"`              //支付方式(SDK,JSAPI)
	PayChannel     string   `json:"pay_channel"`          //支付渠道,为 WXPAY 或 ALIPAY
	SubOpenId      string   `json:"subOpenId"`            //微信小程序返回的 openId
	PayNote        string   `json:"pay_note,omitempty"`   //支付备注
	Currency       string   `json:"currency,omitempty"`   //币种
	PayAmount      string   `json:"pay_amount"`       //支付金额
	GoodsName      string   `json:"goods_name"`        //商品名称  
	GoodsPrice     string   `json:"goods_price"`       //商品单价  
	Quantity       string   `json:"quantity"`          //商品数量
	GoodsDesc      string   `json:"goods_desc"`        //商品描述
	TimeoutExpress string   `json:"timeout_express"`    //订单过期时间
	ClientIp       string   `json:"client_ip,omitempty"` //客户端 ip
}

type PayInfo struct {
	TimeStamp string `json:"timeStamp"`
	Package   string `json:"package"`
	PaySign   string `json:"paySign"`
	AppId     string `json:"appId"`
	SignType  string `json:"signType"`
	NonceStr  string `json:"nonceStr"`
}

/*
{"status":"DUPLICATE_REQUEST_NO","data":"S0001操作成功","message":"重复的请求号"}
{"status":"T","data":{"result":true,"pay_info":null,"sign":"a91a676bc0147d69a911b877aacedd63","sign_type":"MD5"},"message":null}

{"status":"T","data":{"result":true,"pay_info":"{\"appId\":\"wx24635f73e3c8845b\",\"nonceStr\":\"1f3a6cc38f6643b5b5acb05fb94607d5\",\"package\":\"prepay_id=wx2517473969422211cf32bfc84288598087\",\"paySign\":\"5F3C3E74EFA8F5E913D246155DF957C6\",\"signType\":\"MD5\",\"timeStamp\":\"1540460859\"}","sign":"6c11d53cb922575a796f347426855acf","sign_type":"MD5"},"message":null}

*/


func  Unifield(mchId,appSecret,callBackUrl,storeName,
              receviceId,mchOrderNo,subOpenId,currency,payAmount,
			  goodsName,goodsPrice,quantity,goodsDesc,
			  timeoutExpress string) (PayInfo,error){

	url := "https://gate.supaytechnology.com/api/gateway/merchant/order"
	client := core.GetPayJSONClient("POST", url)
	var req = new(UnifieldReq)
	//
	req.Service = "create_instant_trade"
	req.MchId = mchId
	req.Charset = "UTF-8"
	req.SignType = "MD5"
	req.Memo = ""
	req.Version = "1.0"
	//
	req.CallBackUrl = callBackUrl
	req.NotifyUrl = ""
	req.StoreName = storeName
	req.ReceviceId = receviceId
	req.MchOrderNo = mchOrderNo
	req.PayWay = "JSAPI"
	req.PayChannel = "WXPAY"
	req.SubOpenId = subOpenId
	req.PayNote = ""
	req.Currency = currency
	req.PayAmount = payAmount
	req.GoodsName = goodsName
	req.GoodsPrice = goodsPrice
	req.Quantity = quantity
	req.GoodsDesc = goodsDesc
	req.TimeoutExpress = timeoutExpress
	req.ClientIp = ""
	//
	params := mapstruct.Struct2Map(req, "json")
	req.Sign = signature.SuperPayMakeSign(params, appSecret)
	//
	type Data struct {
		Result   bool    `json:"result"`
		Sign     string  `json:"sign"`
		SignType string  `json:"sign_type"`
		PayInfo  string  `json:"pay_info"`
	}
	type UnifiedRsp struct {
		Status  string           `json:"status"`
		Message string           `json:"message"`
		Data    json.RawMessage  `json:"data"`
	}
	var rsp UnifiedRsp
	var data Data
	var payInfoRsp PayInfo
	_, err := client.PayJsonExcute(req, &rsp)
    //beego.Debug("tbdata:", string(tbdata))
	if err != nil {
		return payInfoRsp, err
	}
	if rsp.Status != "T" {
	    returnMsg := rsp.Message
		return payInfoRsp, errors.New(returnMsg)
	}
	err = json.Unmarshal(rsp.Data, &data)
	if err != nil {
		return payInfoRsp, err
	}
	if len(data.PayInfo) < 10 {
		return payInfoRsp, errors.New("PayInfo is invalid")
	}
	// 校验回执签名
	sign := signature.SuperPayRspMakeSign(data.Result,data.PayInfo,appSecret)
	result := strings.EqualFold(data.Sign, sign)
	if !result {
		err = errors.New("response sign err")
		return payInfoRsp, err
	}
	err = json.Unmarshal([]byte(data.PayInfo), &payInfoRsp)
	if err != nil {
		return payInfoRsp, err
	}
	return payInfoRsp, nil
}
